<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input v-model="query.roleName" placeholder="请输入角色名称" @keyup.enter.native="search" clearable />
      <el-select v-model="query.roleType" placeholder="请选择角色类型" clearable>
        <el-option v-for="item in roleTypes" :key="item.key" :label="item.displayName" :value="item.key" />
      </el-select>
      <el-select v-model="query.status" placeholder="请选择状态" clearable>
        <el-option v-for="item in status" :key="item.key" :label="item.displayName" :value="item.key" />
      </el-select>
      <el-button type="primary" icon="el-icon-search" @click="search">
        {{ $t('table.search') }}
      </el-button>
      <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleAddRole">
        新增
      </el-button>
    </div>
    <el-table ref="table" :data="rolesList" row-key="id" highlight-current-row border
      :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
      <el-table-column prop="roleName" label="角色名称" sortable />
      <el-table-column prop="roleType" label="角色类型" sortable>
        <template slot-scope="{row}">
          <span>{{ formatRoleType(row.roleType) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态">
        <template slot-scope="{row}">
          <el-tag v-if="row.status === 0" type="success" effect="dark" size="small">已启用</el-tag>
          <el-tag v-else effect="dark" size="small">未启用</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="创建时间">
        <template slot-scope="{row:{createTime}}">
          <span>{{ createTime && new Date(createTime) | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('table.actions')" align="center">
        <template slot-scope="{row,$index}">
          <el-button type="primary" size="mini" @click="handleEdit(row)">
            {{ $t('table.edit') }}
          </el-button>
          <el-button size="mini" type="danger" @click="handleDelete(row, $index)">
            {{ $t('table.delete') }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="total > 0" :total="total" :page.sync="query.pageIndex" :limit.sync="query.pageSize"
      @pagination="getRoles" />
    <el-dialog :close-on-click-modal="false" :visible.sync="dialogVisible" :title="role.id ? '编辑角色' : '新建角色'">
      <el-form :model="role" ref="roleForm" :rules="rules" label-width="110px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="角色名称" prop="roleName">
              <el-input v-model="role.roleName" placeholder="请输入角色名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色类型" prop="roleType">
              <el-select v-model="role.roleType" placeholder="请选择角色类型">
                <el-option v-for="item in roleTypes" :key="item.key" :label="item.displayName" :value="item.key" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="role.status" size="small">
                <el-radio-button v-for="state in status" :key="state.key" :label="state.key">
                  {{ state.displayName }}
                </el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-loading="isLoading('tree')" label="后台菜单权限">
              <el-tree ref="tree" :check-strictly="checkStrictly" :default-checked-keys="checkedMenus"
                :data="routesData" :props="defaultProps" show-checkbox node-key="path" :expand-on-click-node="true"
                class="permission-tree" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="danger" @click="dialogVisible = false">
          {{ $t('permission.cancel') }}
        </el-button>
        <el-button type="primary" @click="confirmRole">
          {{ $t('permission.confirm') }}
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import path from 'path'
import { asyncRoutes } from '@/router'
import { getRoles, getPermission, addRole, deleteRole, updateRole } from '@/api/role'
import { getMenu, getSettingMenu } from '@/api/appMenu'
import waves from '@/directive/waves' // waves directive
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import { deepClone, arraryRemove } from '../../../utils'
import i18n from '@/lang'

const defaultRole = {
  id: '',
  roleName: '',
  roleType: 0,
  status: 0,
  createTime: new Date().getTime()
}

const status = [
  { key: 0, displayName: '启用' },
  { key: 1, displayName: '禁用' }
]

const roleTypes = [
  { key: 0, displayName: '管理员' },
  { key: 1, displayName: '厂商' },
  // { key: 2, displayName: '供应商' }
]
const cityOptions = ['上海', '北京', '广州', '深圳']
export default {
  name: 'Roles',
  components: { Pagination },
  directives: { waves },
  data() {
    return {
      menus: [],
      checkAll: false,
      checkedAppMenus: [],
      cities: cityOptions,
      isIndeterminate: true,
      routes: [],
      checkedMenus: [],
      dialogVisible: false,
      dialogType: 'new',
      checkStrictly: false,
      defaultProps: {
        children: 'children',
        label: 'title'
      },
      role: Object.assign({}, defaultRole),
      total: 0,
      status: Object.freeze(status),
      roleTypes: Object.freeze(roleTypes),
      query: {
        pageIndex: 1,
        pageSize: 20,
        roleName: '',
        roleType: '',
        status: 0
      },
      rolesList: [],
      loadingList: [],
      rules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        roleType:[
        { required: true, message: '请选择角色类型', trigger: 'change' }
        ]
      }
    }
  },
  computed: {
    routesData() {
      return this.routes
    }
  },
  mounted() {
    // this.getMenuList()
    this.getRoles()
    const routes = this.generateRoutes(asyncRoutes)
    this.routes = this.i18n(routes)
  },
  methods: {
    getSettingmenu(id) {
      getPermission(id).then(res => {
        console.log(res)
        const arr = []

        res.permissionsInfo.forEach(function (item) {
          arr.push(item.menuId)
        })
        let save = []
        this.menus.forEach(function (item, index) {
          save[index] = item.path
        })
        save = save.filter((tab) =>
          arr.some((m) => tab.indexOf(m) !== -1)
        )
        this.checkedAppMenus = save
        console.log('1', this.checkedAppMenus)
      }).catch(err => console.error(err))
    },
    getMenuList() {
      getMenu().then(res => {
        console.log(res)
        this.menus = res.data.list
      }).catch(err => console.error(err))
    },
    i18n(routes) {
      const app = routes.map(route => {
        route.title = i18n.t(`route.${route.title}`)
        if (route.children) {
          route.children = this.i18n(route.children)
        }
        return route
      })
      return app
    },
    getRoles() {
      const table = 'table'
      this.loadingList.push(table)
      getRoles(this.query)
        .then(res => {
          const { list, total } = res
          this.rolesList = list
          this.total = total
        })
        .finally(() => {
          arraryRemove(this.loadingList, table)
        })
    },
    handleCheckedMenuChange(value) {
      const checkedCount = value.length
      this.checkAll = checkedCount === this.cities.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length
    },

    search() {
      this.query.pageIndex = 1
      this.getRoles()
    },
    handleAddRole() {
      this.role = Object.assign({}, defaultRole)
      if (this.$refs.tree) {
        this.$refs.tree.setCheckedNodes([])
      }
      this.dialogType = 'new'
      this.dialogVisible = true
    },
    handleEdit(row) {
      this.getSettingmenu(row.id)

      this.dialogType = 'edit'
      this.dialogVisible = true

      this.role = deepClone(row)
      this.loadingList.push('tree')
      getPermission(this.role.id).then(res => {
        const { permissionsInfo } = res

        const permissions = permissionsInfo.map(p => p.menuId)
        console.log(permissions)
        this.$nextTick(() => {
          this.$refs.tree.setCheckedKeys(permissions)
        })
      }).finally(() => {
        setTimeout(() => {
          arraryRemove(this.loadingList, 'tree')
        }, 500)
      })
    },
    handleDelete(row, $index) {
      this.$confirm('确认删除角色?', '警告', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        await deleteRole(row.id)
        this.rolesList.splice($index, 1)
        this.$message({
          type: 'success',
          message: '删除成功!'
        })
      }).catch(err => console.error(err))
    },
    // Reshape the routes structure so that it looks the same as the sidebar
    generateRoutes(routes, basePath = '/') {
      const res = []

      for (let route of routes) {
        // skip some route
        if (route.hidden) { continue }

        const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route)

        if (route.children && onlyOneShowingChild && !route.alwaysShow) {
          route = onlyOneShowingChild
        }
        const data = {
          path: path.resolve(basePath, route.path),
          title: route.meta && route.meta.title
        }
        if (route.children) {
          data.children = this.generateRoutes(route.children, data.path)
        }
        res.push(data)
      }
      return res
    },
    generateTree(routes, basePath = '/', checkedKeys) {
      const res = []

      for (const route of routes) {
        const routePath = path.resolve(basePath, route.path)

        // recursive child routes
        if (route.children) {
          route.children = this.generateTree(route.children, routePath, checkedKeys)
        }

        if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) {
          res.push(route)
        }
      }
      return res
    },
    generateArr(routes) {
      let data = []
      routes.forEach(route => {
        data.push(route)
        if (route.children) {
          const temp = this.generateArr(route.children)
          if (temp.length > 0) {
            data = [...data, ...temp]
          }
        }
      })
      return data
    },
    // reference: src/view/layout/components/Sidebar/SidebarItem.vue
    onlyOneShowingChild(children = [], parent) {
      let onlyOneChild = null
      const showingChildren = children.filter(item => !item.hidden)

      // When there is only one child route, the child route is displayed by default
      if (showingChildren.length === 1) {
        onlyOneChild = showingChildren[0]
        onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path)
        return onlyOneChild
      }

      // Show parent if there are no child route to display
      if (showingChildren.length === 0) {
        onlyOneChild = { ...parent, path: '', noShowingChildren: true }
        return onlyOneChild
      }

      return false
    },
    async confirmRole() {
      this.$refs['roleForm'].validate(async (valid) => {
        if (valid) {
          const isEdit = this.dialogType === 'edit'
          const checkedPermissions = this.$refs.tree.getCheckedKeys()
          const permission = {
            role: { ...this.role },
            permissionsInfo: this.getPermissionsInfo(checkedPermissions)
          }
          this.$nextTick(function () {
            for (var i = 0; i < this.checkedAppMenus.length; i++) {
              permission.permissionsInfo.push({ 'menuId': this.checkedAppMenus[i] })
            }
          })
          if (isEdit) {
            await updateRole(this.role.id, permission)
            for (let index = 0; index < this.rolesList.length; index++) {
              if (this.rolesList[index].id === this.role.id) {
                this.rolesList.splice(index, 1, Object.assign({}, this.role))
                break
              }
            }
          } else {
            const { role } = await addRole(permission)
            this.role.id = role.id
            this.rolesList.push(this.role)
          }

          this.dialogVisible = false
          this.$message.success('新增成功')
        }
      })

    },
    getPermissionsInfo(checkedPermissions) {
      return checkedPermissions.map(path => {
        return {
          menuId: path
        }
      })
    },
    getMenus(checkedPermissions) {
      return checkedPermissions.map(path => {
        return {
          menuId: path
        }
      })
    },
    formatRoleType(roleType) {
      const rt = this.roleTypes.find(rt => rt.key === roleType)
      return rt ? rt.displayName : ''
    },
    isLoading(name) {
      return this.loadingList.includes(name)
    }
  }
}
</script>
